package com.wxit.algorithm.link;

import java.util.Iterator;
import java.util.function.Consumer;

public class SinglyLinkedList implements Iterable<Integer> {

    private Node head = null; //头部节点

    /**
     * 头部添加
     * @param value
     */
    public void addFirst(int value) {
        head = new Node(value, this.head);
    }

    /**
     * 遍历
     */
    public void loop01() {
        Node p = head;
        while (p != null) {
            System.out.println(p.value);
            p = p.next;
        }
    }

    /**
     * while遍历
     * @param consumer
     */
    public void loop(Consumer<Integer> consumer) {
        Node current = this.head;
        while (current != null) {
            consumer.accept(current.value);
            current = current.next;
        }
    }

    /**
     * for循环遍历
     */
    public void loop02(Consumer<Integer> consumer) {
        for (Node current = this.head; current != null; current = current.next) {
            consumer.accept(current.value);
        }
    }




    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            Node current = head;
            @Override
            public boolean hasNext() {
                return current != null;
            }

            @Override
            public Integer next() {
                int value = current.value;
                current = current.next;

                return value;
            }
        };
    }

    /**
     * 找到最后一个节点
     */
    private Node findLast() {
        if (head == null) {
            return null;
        }

        Node p;
        for (p = head; p.next != null; p = p.next) {

        }
        return p;
    }

    public void addLast(int value) {
        Node last = findLast();
        if (last == null) {
            addFirst(value);
            return;
        }
        last.next = new Node(value, null);
    }

    /**
     * 查找索引对应的Node
     */
    private Node findNode(int value) {
        int i = 0;
        for (Node p = head; p != null; p = p.next, i++) {
            if (i == value) {
                return p;
            }
        }
        return null;
    }

    public int get(int index) {
        Node p = findNode(index);
        if (p == null) {
            throw illegalArgumentException(index);
        }
        return p.value;
    }

    private static IllegalArgumentException illegalArgumentException(int index) {
        return new IllegalArgumentException(String.format("index [%d] 不合法\n", index));
    }

    /**
     * 任意索引位置添加元素
     */
    public void insert(int index, int value) {
        //找到上一个节点
        if (index == 0) {
            addFirst(value);
            return;
        }
        Node prev = findNode(index - 1);
        if (prev == null) {
            throw illegalArgumentException(index);
        }
        prev.next = new Node(value, prev.next);
    }

    /**
     * 删除第一个元素
     */
    public void removeFirst() {
        if (head == null) {
            throw illegalArgumentException(0);
        }
        head = head.next;
    }

    /**
     * 删除任意位置的元素
     * @param value
     */
    public void remove(int value) {
        //找到上一个节点，让上一个节点的指针指向被删除节点的下一个元素
        if (value == 0) {
            removeFirst();
            return;
        }
        Node prev = findNode(value - 1);
        if (prev == null) {
            throw illegalArgumentException(value);
        }
        Node remove = findNode(value);
        if (remove == null) {
            throw illegalArgumentException(value);
        }
        prev.next = remove.next;
    }

    public void loop3(Consumer<Integer> before, Consumer<Integer> after)
    {
        recursion(head, before, after);
    }
    /**
     * 某个节点要进行的操作
     */
    private void recursion(Node current, Consumer<Integer> before, Consumer<Integer> after) {
        if (current == null) {
            return;
        }
        before.accept(current.value);
        recursion(current.next, before, after);
        after.accept(current.value);
    }
}
